/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.namabank.servlet;

import com.namabank.db.GlobalHibernate;
import com.namabank.exception.CheckValidate;
import com.namabank.helpdesk.model.CurrentUserModel;
import com.namabank.helpdesk.model.UserModel;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.namabank.util.*;
import javax.servlet.ServletConfig;
import org.apache.log4j.*;
import org.json.JSONObject;

/**
 *
 * @author Tran Hien
 */
public class BaseServlet extends HttpServlet {

    public static Boolean developing = null;
    public static Boolean fordebug = null;
    protected static Boolean force_stop = false;
    protected static Boolean check_user_online = null;
    Logger logger = org.apache.log4j.Logger.getLogger(BaseServlet.class);
    static Boolean loadedConfig = false;

    JSONObject login(String userid, String hpwd) throws Exception {
        JSONObject res = new JSONObject();

        res.put("result", "error");
        if (CheckValidate.isNullOrEmpty(userid, "userid", res)) {
            return res;
        }
        if (CheckValidate.isNullOrEmpty(hpwd, "hdPassword", res)) {
            return res;
        }
        UserModel nUserModel = null;

        nUserModel = UserModel.getInstance(userid);

        if (nUserModel == null || !hpwd.equals(nUserModel.getSmtbUserObj().getUSER_PASSWORD())) {
            res.put("error_name", "access_denied");
            res.put("error_type", "wrong_userid_or_pass");
            res.put("error_data", userid);
            return res;
        }
        if (nUserModel.getSmtbUserObj().getRECORD_STAT() != 'O') {
            res.put("error_name", "access_denied");
            res.put("error_type", "account_blocked");
            res.put("error_data", userid);
            return res;
        }
        res.put("result", "successful");
        res.put("user_id", userid);
        res.put("user_obj", nUserModel);
        return res;
    }

    //<editor-fold defaultstate="collapsed" desc="Những hàm protected cho lớp con override">
    protected void mainProcess(EvaluateParam evalparam) {
    }
    //</editor-fold>

    /**
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("text/html;charset=UTF-8");
        response.setHeader("Cache-Control", "no-cache"); //HTTP 1.1
        response.setHeader("Pragma", "no-cache"); //HTTP 1.0
        response.setDateHeader("Expires", 0); //prevents caching at the proxy server
        request.setCharacterEncoding("UTF-8");

        EvaluateParam evalparam = (EvaluateParam)request.getAttribute("evalparam");

        if(evalparam == null){
            evalparam = new EvaluateParam(request);
        }
        HttpSession session = request.getSession();
        String state = request.getParameter("state");
        boolean isRequestLogin = "login".equals(state);
        boolean isDispatch = false;
        String usingModule = null;
        String loginPage = "/index.jsp";
        String framePage = "/application.jsp";
        try {
            String clientSessionId = evalparam.getTrimmedNotEmptyParameter("sessionid");
            JSONObject jsonLoginInfo = null;
            CurrentUserModel curLogObj = null;

            if ("logout".equals(state)) {
                response.sendRedirect(HttpUtil.getFullHTTPPath(request, loginPage) + "?logout=true");
            }
            if (clientSessionId == null || isRequestLogin) {
                String clientUserId = evalparam.getTrimmedNotEmptyParameter("userid");
                String clientPassword = evalparam.getTrimmedNotEmptyParameter("hdPassword");
                String userId = null;
                if (clientUserId == null || clientPassword == null) {
                    if (clientUserId == null) {
                        evalparam.setResponseError("Bạn chưa nhập <b>username</b>");
                    } else {
                        evalparam.setResponseError("Bạn chưa nhập <b>password</b>");
                    }
                    request.setAttribute("evalparam", evalparam);
                    request.getRequestDispatcher(loginPage).forward(request, response);
                    isDispatch = true;
                    return;
                }
                String[] m = clientUserId.split("/");
                userId = m[0];
                if (m.length > 1) {
                    usingModule = m[1].trim();
                }

                jsonLoginInfo = login(userId, clientPassword);
                if ("error".equals(jsonLoginInfo.opt("result"))) {
                    String errorType = jsonLoginInfo.optString("error_type");
                    String errorData = jsonLoginInfo.optString("error_data");
                    if ("wrong_userid_or_pass".equals(errorType)) {
                        evalparam.setResponseError("Thông tin đăng nhập không hợp lệ, bạn kiểm tra lại username và password");
                    } else if ("account_blocked".equals(errorType)) {
                        evalparam.setResponseError("Tài khoản <b>" + errorData + "</b> đã bị khóa trên hệ thống Helpdesk");
                    } else if ("have_not_role".equals(errorType)) {
                        evalparam.setResponseError("Tài khoản <b>" + errorData + "</b> không có quyền truy cập chương trình");
                    }
                    if (isRequestLogin) {
                        request.setAttribute("evalparam", evalparam);
                        request.getRequestDispatcher(loginPage).forward(request, response);
                        isDispatch = true;
                    }
                    return;
                }
                UserModel userModel = (UserModel)jsonLoginInfo.get("user_obj");
                boolean makeLogLogin = false;
                if(clientSessionId == null){
                    clientSessionId = java.util.UUID.randomUUID().toString().toLowerCase();
                    makeLogLogin = true;
                } else{
                    curLogObj = CurrentUserModel.getBySessionId(clientSessionId);
                }
                if(curLogObj == null){
                    curLogObj = new CurrentUserModel();
                    curLogObj.setSessionId(clientSessionId);
                }
                evalparam.setUserModel(userModel);
                evalparam.setCurrentUserModel(curLogObj);
                curLogObj.setClientInfo(evalparam.getClientInfo());
                curLogObj.setUserInfo(userModel);

                GlobalHibernate.openSession().save(curLogObj.getDbObj());
                if(makeLogLogin)
                    GlobalHibernate.openSession().save(curLogObj.genLogObj());
                session.setAttribute(clientSessionId, evalparam.exportData());
            } else {
                JSONObject json = null;
                if (clientSessionId != null) {
                    json = (JSONObject) session.getAttribute(clientSessionId);
                    if (json == null) {
                        curLogObj = CurrentUserModel.getBySessionId(clientSessionId);
                        if(curLogObj != null){
                            json = new JSONObject();
                            json.put("user_id", curLogObj.getUserId());
                            json.put("user_model", UserModel.getInstance(curLogObj.getUserId()));
                            json.put("current_user_model", curLogObj);
                        }
                    }
                }
                if (json == null || !evalparam.importData(json)) {
                    if(this instanceof BaseServlet){
                        response.sendRedirect(HttpUtil.getFullHTTPPath(request, loginPage));
                        return;
                    }
                    evalparam.setResponseRedirect("Bạn vui lòng đăng nhập", HttpUtil.getFullHTTPPath(request, loginPage));
                    return;
                }
            }

            if (isRequestLogin) {
                request.setAttribute("evalparam", evalparam);
                request.setAttribute("sessionid", clientSessionId);
                request.getRequestDispatcher(framePage).forward(request, response);
                isDispatch = true;
            } else {
                GlobalHibernate.openSession().clear();
                mainProcess(evalparam);
            }

        } catch (Exception ex) {
            logger.error("Loi khi xu ly", ex);
            evalparam.setResponseError(ex.toString());
        } finally {
            if (!isDispatch) {
                try {
                    closeResponse(response, evalparam);
                } catch (Exception ex1) {
                    logger.error("Loi khi gui ket qua tra ve", ex1);
                    PrintWriter out = response.getWriter();
                    out.print("Chương trình có lỗi khi xử lý, vui lòng liên hệ với hỗ trợ để thông báo tình hình, cảm ơn.");
                    out.flush();
                    out.close();
                }
            } else {
                GlobalHibernate.closeAllSession(evalparam.getCommitWhenClose());
            }
        }
    }

    protected void closeResponse(HttpServletResponse response, EvaluateParam evalparam) throws InterruptedException, IOException {
        if (!GlobalHibernate.closeAllSession(evalparam.getCommitWhenClose())) {
            evalparam.clearResponseText();
            evalparam.setResponseError("Có lỗi kết nối với database, vui lòng liên hệ với hỗ trợ để thông báo tình hình, cảm ơn.");
        }
        if (!evalparam.getIsSendFile()) {
            PrintWriter out = response.getWriter();
            out.print(evalparam.getResponseString());
            out.flush();
            out.close();
        }
    }

    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
    }


    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /**
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>
}
